package com.yinchuang.aiuidemo;

import android.util.Log;

/**
 * Created by lingchen on 2020/3/6. 12:00
 * mail:lingchen52@foxmail.com
 */
public class DbUtils {
    private static String TAG = DbUtils.class.getSimpleName();

    public static int getDb(byte[] data) {
        double sum = 0;
        double ave;
        int length = data.length > 128 ? 128 : data.length;
        int offsetStart = 8;
        for (int i = offsetStart; i < length; i++) {
            sum += data[i];
        }
        ave = (sum / (length - offsetStart)) * 65536 / 128f;
        int i = (int) (Math.log10(ave) * 20);
        return i < 0 ? 27 : i;
    }

    /**
     * 获取分贝采样值  8个采样值  间隔125/8ms
     *
     * @param buffer
     */
    public static void getPcmDbSampling(byte[] buffer) {
        short[] data = bytes2Shorts(buffer);

        int[] array_db = new int[8];
        array_db[0] = getDb(data, 0);
        array_db[1] = getDb(data, data.length / 8);
        array_db[2] = getDb(data, data.length / 4);
        array_db[3] = getDb(data, data.length / 8 * 3);
        array_db[4] = getDb(data, data.length / 2);
        array_db[5] = getDb(data, data.length / 8 * 5);
        array_db[6] = getDb(data, data.length / 4 * 3);
        array_db[7] = getDb(data, data.length / 8 * 7);

        mathDbArray(array_db);
    }

    /**
     * 计算最大值、最小值、平均值
     *
     * @param data
     */
    public static void mathDbArray(int[] data) {
        int max = data[0];
        int min = data[0];
        int sum = 0;
        for (int i = 0; i < data.length; i++) {
            sum += data[i];
            if (max < data[i]) {
                max = data[i];
            }
            if (min > data[i]) {
                min = data[i];
            }
        }
        int avg = sum / data.length;
        Log.e(TAG, "db max = " + max + ", db min = " + min + ", db avg = " + avg);
    }

    /**
     * 获取分贝值
     *
     * @param data
     * @param start
     * @return
     */
    public static int getDb(short[] data, int start) {
        float BASE = 32768.0f;
        double maxAmplitude = 0;
        for (int i = start; i < start + data.length / 8; i++) {
            maxAmplitude += data[i] * data[i];
        }
        maxAmplitude = (float) Math.sqrt(maxAmplitude / (data.length / 8));
        double ratio = maxAmplitude / BASE;
        int db = 0;
        if (ratio > 0) {
            db = (int) (20 * Math.log10(ratio)) + 100;
        }
        Log.e(TAG, "getPcmDb:db = " + db + ", readSize = " + (data.length / 8));
        return db;
    }

    /**
     * byte[]转short[]
     *
     * @param buffer
     * @return
     */
    private static short[] bytes2Shorts(byte[] buffer) {
        short[] data = new short[buffer.length / 2];
        for (int i = 0; i < buffer.length / 2; i++) {
            data[i] = (short) doubleByte2Int(buffer[i * 2], buffer[i * 2 + 1]);
        }
        return data;
    }

    /**
     * 两个相邻byte转int 低8位在前，高8位在后
     *
     * @return
     */
    public static int doubleByte2Int(byte byte1, byte byte2) {
        return (byte2 & 0xff) << 8
                | (byte1 & 0xff);
    }
}
